//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.tuiofx;

import java.util.Iterator;
import java.util.Properties;
import javafx.application.Application;
import javafx.event.EventTarget;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.tuiofx.internal.base.CoordinatesMapping;
import org.tuiofx.internal.base.GestureHandler;
import org.tuiofx.internal.base.TargetSelection;
import org.tuiofx.internal.base.TouchHandler;
import org.tuiofx.internal.base.TuioInputService;
import org.tuiofx.internal.util.LogUtils;

public class TuioFX {
    private static boolean INITIALIZED = false;
    private final Configuration config;
    private Stage stage = null;
    private TouchHandler touchHandler = null;
    private GestureHandler gestureHandler = null;
    private TuioInputService tuioInputService = null;
    private Scene scene;
    private static final String STYLESHEET_TUIOFX = "org/tuiofx/widgets/skin/tuiofx/tuiofx.css";
    private boolean isStarted = false;
    private CoordinatesMapping coordinatesMapping;
    private TargetSelection targetSelection;

    public static void enableJavaFXTouchProperties() {
        Properties props = System.getProperties();
        props.setProperty("com.sun.javafx.touch", "true");
        props.setProperty("com.sun.javafx.multiTouch", "true");
        props.setProperty("com.sun.javafx.virtualKeyboard", "none");
        INITIALIZED = true;
    }

    public TuioFX(Stage stage, Configuration config) {
        this.stage = stage;
        this.scene = stage.getScene();
        this.config = config;
        this.initLogger(config);
    }

    private void initLogger(Configuration config) {
        if (config.isDebugModeEnabled()) {
            System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "debug");
        }
    }

    public void start() {
        this.checkNotStarted();
        this.isStarted = true;
        this.checkNotNull(this.stage);
        this.scene = this.stage.getScene();
        if (this.scene != null) {
            this.createTouchInputProcessors(this.scene);
        }

        this.stage.sceneProperty().addListener((observable, oldScene, newScene) -> {
            this.scene = newScene;
            LogUtils.debug("Scene changed to " + newScene);
            this.createTouchInputProcessors(this.scene);
        });
    }

    private void disconnectTuioClient() {
        if (this.tuioInputService != null) {
            this.tuioInputService.disconnectTUIO();
        }

    }

    private void createTouchInputProcessors(Scene scene) {
        if (this.gestureHandler == null) {
            this.gestureHandler = new GestureHandler(this.config);
        }

        if (this.touchHandler == null) {
            this.targetSelection = new TargetSelection(scene, this.config);
        }

        if (this.coordinatesMapping == null) {
            this.coordinatesMapping = new CoordinatesMapping(this.stage, this.config);
        }

        if (this.touchHandler == null) {
            this.touchHandler = new TouchHandler(this.gestureHandler, this.targetSelection, this.coordinatesMapping, this.config);
        }

        if (this.tuioInputService == null) {
            this.tuioInputService = new TuioInputService(this.coordinatesMapping, this.touchHandler, this.config);
        }

    }

    private void stopInputProcessors() {
        this.touchHandler = null;
        this.tuioInputService = null;
        this.gestureHandler = null;
    }

    private void checkNotStarted() {
        if (this.isStarted) {
            throw new IllegalStateException("TUIOFX is already running.");
        }
    }

    private <T> T checkNotNull(T reference) {
        if (reference == null) {
            throw new NullPointerException();
        } else {
            return reference;
        }
    }

    private <T> T checkNotNull(T reference, String message) {
        if (reference == null) {
            throw new NullPointerException(message);
        } else {
            return reference;
        }
    }

    public void enableMTWidgets(boolean enable) {
        if (!INITIALIZED) {
            LogUtils.debug("TUIOFX has not been initialized.");
        }

        if (enable) {
            Application.setUserAgentStylesheet("MODENA");
            //StyleManager.getInstance().addUserAgentStylesheet("org/tuiofx/widgets/skin/tuiofx/tuiofx.css");
            LogUtils.debug("add user agent: "+"org/tuiofx/widgets/skin/tuiofx/tuiofx.css");
        } else {
            //StyleManager.getInstance().removeUserAgentStylesheet("org/tuiofx/widgets/skin/tuiofx/tuiofx.css");
        }

    }

    public void addTangibleListener(TangibleListener listener) {
        this.checkNotNull(this.tuioInputService, "TUIOFX must be started before adding tangible listeners and scene must be set.");
        this.tuioInputService.addTangibleListener(listener);
    }

    public void removeTangibleListener(TangibleListener listener) {
        this.checkNotNull(this.tuioInputService, "TUIOFX must start before removing tangible listeners.");
        this.tuioInputService.removeTangibleListener(listener);
    }

    public void removeAllTangibleListener() {
        this.checkNotNull(this.tuioInputService, "TUIOFX must start before removing tangible listeners.");
        this.tuioInputService.removeAllTangibleListener();
    }

    public void stop() {
        this.disconnectTuioClient();
        if (this.tuioInputService != null) {
            this.removeAllTangibleListener();
        }

        this.stopInputProcessors();
        this.isStarted = false;
    }

    public static void startFullDrag(EventTarget source) {
        Node node = (Node)source;
        dump(node);
    }

    private static void dump(Node node) {
        System.out.print(">  ");
        System.out.println(node);
        if (node instanceof Parent) {
            Iterator var1 = ((Parent)node).getChildrenUnmodifiable().iterator();

            while(var1.hasNext()) {
                Node c = (Node)var1.next();
                dump(c);
            }
        }

        node.getProperties().put("startFullDrag", "true");
    }
}
